package seed_variant

import (
	"errors"
	"math"
	"strconv"

	"github.com/jinzhu/gorm"

	"github.com/gin-gonic/gin"

	rich_err "app/error"
	"app/models"
	"app/service"
)

func Gets(context *gin.Context) ([]*models.SeedVariantDetail, *models.Pager, *rich_err.RichError) {
	base := models.Orm.Model(&models.SeedVariant{}).
		Select("seed_variant.*, seed_category.name as category_name").
		Joins("LEFT JOIN seed_category ON seed_variant.category_id = seed_category.id")

	results, pager, err := service.GetDetails[models.SeedVariantDetail](context, base, models.SeedVariant{}.TableName(), map[string]string{"category_name": "seed_category.name"})

	if err != nil {
		return nil, nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	return results, pager, nil
}

func Get(id string) (*models.SeedVariantDetail, *rich_err.RichError) {
	base := models.Orm.Model(&models.SeedVariant{}).
		Select("seed_variant.*, seed_category.name as category_name").
		Joins("LEFT JOIN seed_category ON seed_variant.category_id = seed_category.id")

	result, err := service.GetDetail[models.SeedVariantDetail](id, base)

	if err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	return result, nil
}

func Create(context *gin.Context) (*models.SeedVariantDetail, *rich_err.RichError) {
	req := new(models.SeedVariantCore)
	if err := context.ShouldBindJSON(req); err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	// 检查是否存在相同名称的记录
	var existing models.SeedVariant
	if err := models.Orm.Where("name = ?", req.Name).First(&existing).Error; err == nil {
		// 如果找到记录，直接返回
		return Get(strconv.Itoa(existing.ID))
	} else if !errors.Is(err, gorm.ErrRecordNotFound) {
		// 如果查询出错，返回数据库错误
		return nil, rich_err.NewError(rich_err.DatabaseFailed, err)
	}
	data := models.SeedVariant{SeedVariantCore: *req}
	result := models.Orm.Create(&data)
	if result.Error != nil {
		return nil, rich_err.NewError(rich_err.DatabaseFailed, result.Error)
	}
	return Get(strconv.Itoa(data.ID))
}

func Update(context *gin.Context) (*models.SeedVariantDetail, *rich_err.RichError) {
	req := new(models.SeedVariantDelta)
	if err := context.ShouldBindJSON(req); err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}

	data, err := service.Get[models.SeedVariant](context)
	if err != nil {
		return nil, rich_err.NewError(rich_err.RequestInvalid, err)
	}
	if req.Name != nil {
		data.Name = req.Name.(string)
	}
	if req.Remark != nil {
		data.Remark = req.Remark.(string)
	}

	if req.IsActive != nil {
		data.IsActive = int(math.Round(req.IsActive.(float64)))
	}
	if req.CategoryID != nil {
		data.CategoryID = int(math.Round(req.CategoryID.(float64)))
	}
	result := models.Orm.Save(data)
	if result.Error != nil {
		return nil, rich_err.NewError(rich_err.DatabaseFailed, result.Error)
	}
	return Get(strconv.Itoa(data.ID))
}

func Delete(context *gin.Context) *rich_err.RichError {
	data, err := service.Get[models.SeedVariant](context)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil
		}
		return rich_err.NewError(rich_err.RequestInvalid, err)
	}
	result := models.Orm.Delete(data)
	if result.Error != nil {
		return rich_err.NewError(rich_err.DatabaseFailed, result.Error)
	}
	return nil
}
